package com.kexio.common.utils;

import com.kexio.common.exception.BusinessException;

import java.util.Collection;
import java.util.function.Supplier;

/**
 * 验证工具类
 * 
 * 提供常用的参数验证方法
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public final class ValidationUtils {
    
    // ==================== 私有构造函数 ====================
    
    private ValidationUtils() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }
    
    // ==================== 基础验证方法 ====================
    
    /**
     * 验证对象不能为空
     * 
     * @param obj 待验证对象
     * @param message 错误消息
     * @throws BusinessException 如果对象为空
     */
    public static void notNull(Object obj, String message) {
        if (obj == null) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证对象不能为空
     * 
     * @param obj 待验证对象
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果对象为空
     */
    public static void notNull(Object obj, Supplier<String> messageSupplier) {
        if (obj == null) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    /**
     * 验证字符串不能为空或空白
     * 
     * @param str 待验证字符串
     * @param message 错误消息
     * @throws BusinessException 如果字符串为空或空白
     */
    public static void notBlank(String str, String message) {
        if (StringUtils.isBlank(str)) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证字符串不能为空或空白
     * 
     * @param str 待验证字符串
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果字符串为空或空白
     */
    public static void notBlank(String str, Supplier<String> messageSupplier) {
        if (StringUtils.isBlank(str)) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    /**
     * 验证集合不能为空
     * 
     * @param collection 待验证集合
     * @param message 错误消息
     * @throws BusinessException 如果集合为空
     */
    public static void notEmpty(Collection<?> collection, String message) {
        if (collection == null || collection.isEmpty()) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证集合不能为空
     * 
     * @param collection 待验证集合
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果集合为空
     */
    public static void notEmpty(Collection<?> collection, Supplier<String> messageSupplier) {
        if (collection == null || collection.isEmpty()) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    /**
     * 验证数组不能为空
     * 
     * @param array 待验证数组
     * @param message 错误消息
     * @throws BusinessException 如果数组为空
     */
    public static void notEmpty(Object[] array, String message) {
        if (array == null || array.length == 0) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证数组不能为空
     * 
     * @param array 待验证数组
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果数组为空
     */
    public static void notEmpty(Object[] array, Supplier<String> messageSupplier) {
        if (array == null || array.length == 0) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    // ==================== 条件验证方法 ====================
    
    /**
     * 验证条件必须为真
     * 
     * @param condition 待验证条件
     * @param message 错误消息
     * @throws BusinessException 如果条件为假
     */
    public static void isTrue(boolean condition, String message) {
        if (!condition) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证条件必须为真
     * 
     * @param condition 待验证条件
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果条件为假
     */
    public static void isTrue(boolean condition, Supplier<String> messageSupplier) {
        if (!condition) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    /**
     * 验证条件必须为假
     * 
     * @param condition 待验证条件
     * @param message 错误消息
     * @throws BusinessException 如果条件为真
     */
    public static void isFalse(boolean condition, String message) {
        if (condition) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证条件必须为假
     * 
     * @param condition 待验证条件
     * @param messageSupplier 错误消息提供者
     * @throws BusinessException 如果条件为真
     */
    public static void isFalse(boolean condition, Supplier<String> messageSupplier) {
        if (condition) {
            throw BusinessException.of(messageSupplier.get());
        }
    }
    
    // ==================== 数值验证方法 ====================
    
    /**
     * 验证数值必须为正数
     * 
     * @param number 待验证数值
     * @param message 错误消息
     * @throws BusinessException 如果数值不是正数
     */
    public static void isPositive(Number number, String message) {
        notNull(number, message);
        if (number.doubleValue() <= 0) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证数值必须为非负数
     * 
     * @param number 待验证数值
     * @param message 错误消息
     * @throws BusinessException 如果数值为负数
     */
    public static void isNotNegative(Number number, String message) {
        notNull(number, message);
        if (number.doubleValue() < 0) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证数值必须在指定范围内
     * 
     * @param number 待验证数值
     * @param min 最小值（包含）
     * @param max 最大值（包含）
     * @param message 错误消息
     * @throws BusinessException 如果数值不在范围内
     */
    public static void inRange(Number number, Number min, Number max, String message) {
        notNull(number, message);
        notNull(min, message);
        notNull(max, message);
        
        double value = number.doubleValue();
        double minValue = min.doubleValue();
        double maxValue = max.doubleValue();
        
        if (value < minValue || value > maxValue) {
            throw BusinessException.of(message);
        }
    }
    
    // ==================== 字符串格式验证方法 ====================
    
    /**
     * 验证手机号格式
     * 
     * @param mobile 手机号
     * @param message 错误消息
     * @throws BusinessException 如果手机号格式不正确
     */
    public static void isValidMobile(String mobile, String message) {
        if (!StringUtils.isValidMobile(mobile)) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证邮箱格式
     * 
     * @param email 邮箱
     * @param message 错误消息
     * @throws BusinessException 如果邮箱格式不正确
     */
    public static void isValidEmail(String email, String message) {
        if (!StringUtils.isValidEmail(email)) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证身份证号格式
     * 
     * @param idCard 身份证号
     * @param message 错误消息
     * @throws BusinessException 如果身份证号格式不正确
     */
    public static void isValidIdCard(String idCard, String message) {
        if (!StringUtils.isValidIdCard(idCard)) {
            throw BusinessException.of(message);
        }
    }
    
    // ==================== 长度验证方法 ====================
    
    /**
     * 验证字符串长度必须在指定范围内
     * 
     * @param str 待验证字符串
     * @param minLength 最小长度（包含）
     * @param maxLength 最大长度（包含）
     * @param message 错误消息
     * @throws BusinessException 如果长度不在范围内
     */
    public static void lengthBetween(String str, int minLength, int maxLength, String message) {
        notNull(str, message);
        int length = str.length();
        if (length < minLength || length > maxLength) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证字符串最小长度
     * 
     * @param str 待验证字符串
     * @param minLength 最小长度（包含）
     * @param message 错误消息
     * @throws BusinessException 如果长度小于最小值
     */
    public static void minLength(String str, int minLength, String message) {
        notNull(str, message);
        if (str.length() < minLength) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证字符串最大长度
     * 
     * @param str 待验证字符串
     * @param maxLength 最大长度（包含）
     * @param message 错误消息
     * @throws BusinessException 如果长度大于最大值
     */
    public static void maxLength(String str, int maxLength, String message) {
        notNull(str, message);
        if (str.length() > maxLength) {
            throw BusinessException.of(message);
        }
    }
    
    /**
     * 验证集合大小必须在指定范围内
     * 
     * @param collection 待验证集合
     * @param minSize 最小大小（包含）
     * @param maxSize 最大大小（包含）
     * @param message 错误消息
     * @throws BusinessException 如果大小不在范围内
     */
    public static void sizeBetween(Collection<?> collection, int minSize, int maxSize, String message) {
        notNull(collection, message);
        int size = collection.size();
        if (size < minSize || size > maxSize) {
            throw BusinessException.of(message);
        }
    }
}
